/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup TeeTrusted
 * @{
 *
 * @brief TEE（Trusted Excution Environment）可信执行环境API。
 *
 * 提供安全能力API，例如可信存储、加解密及可信时间等，用于可信应用程序开发。
 *
 * @since 20
 */

/**
 * @file rpmb_fcntl.h
 *
 * @brief 提供与RPMB服务相关的API。
 *
 * @library NA
 * @kit TEEKit
 * @include <TEEKit/rpmb_fcntl.h>
 * @syscap SystemCapability.Tee.TeeClient
 * @since 20
 */

#ifndef RPMB_RPMB_FCNTL_H
#define RPMB_RPMB_FCNTL_H

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 分区初始化，执行RPMB密钥写入和格式化操作。
 *
 * @attention 此函数只需执行一次。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_RPMB_GENERIC：RPMB控制器一般错误。\n
 *         TEE_ERROR_RPMB_MAC_FAIL：表示RPMB控制器MAC校验错误。\n
 *         TEE_ERROR_RPMB_RESP_UNEXPECT_MAC：表示RPMB响应数据MAC校验错误。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Init(void);

/**
 * @brief RPMB安全存储完全格式化操作。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_RPMB_GENERIC：RPMB控制器一般错误。\n
 *         TEE_ERROR_RPMB_MAC_FAIL：表示RPMB控制器MAC校验错误。\n
 *         TEE_ERROR_RPMB_RESP_UNEXPECT_MAC：表示RPMB响应数据MAC校验错误。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Format(void);

/**
 * @brief 写文件到RPMB。
 *
 * @attention 如果要提高写文件的性能，需要在TA的manifest中定义堆大小，至少是文件大小的三倍加256KB。
 * 例如：要写入一个100KB大小的文件，定义的堆大小至少是556KB（3 * 100 + 256）。如果无法满足堆大小要求，
 * 文件写入仍会成功，但性能会较差。
 *
 * @param filename 表示要写入数据的文件名，最大长度为64字节。
 * @param buf 表示写入数据的缓冲区。
 * @param size 表示写入数据的大小，最大为160KB。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：表示输入参数不正确，或者文件名超过64字节。\n
 *         TEE_ERROR_RPMB_NOSPC：表示RPMB分区磁盘空间不足。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Write(const char *filename, const uint8_t *buf, size_t size);

/**
 * @brief 通过huk2加密方式向RPMB写入文件。
 *
 * @attention 如果希望提升文件写入性能，需要在TA的manifest文件中定义堆大小，至少为文件大小的3倍加上256KB。
 * 例如：写入一个大小为100KB的文件时，定义的堆大小至少为556KB（3 * 100 + 256）。如果堆大小不足，文件写入仍会成功，
 * 但性能会较差。
 *
 * @param filename 表示要写入数据的文件名，最大长度为64字节。
 * @param buf 表示用于写入数据的缓冲区。
 * @param size 表示写入数据的大小，最大为160KB。
 * @param fmode 表示写入数据使用的加密方式，本接口指定使用huk2加密。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数错误，或文件名超过64字节。\n
 *         TEE_ERROR_RPMB_NOSPC：RPMB分区空间不足。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Write_Attr(const char *filename, const uint8_t *buf, size_t size, uint32_t fmode);

/**
 * @brief 从RPMB读取文件。
 *
 * @attention 如果要提高读取文件的性能，需要在TA的manifest中定义堆大小，至少是文件大小的三倍加256KB。
 * 例如：要读取一个100KB大小的文件，定义的堆大小至少是556KB（3 * 100 + 256）。如果无法满足堆大小要求，
 * 文件读取仍会成功，但性能会较差。
 *
 * @param filename 表示要读取数据的文件名，最大长度为64字节。
 * @param buf 表示读取数据的缓冲区。
 * @param size 表示读取数据的大小。
 * @param count 表示实际读取的大小。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确，或者文件名超过64字节。\n
 *         TEE_ERROR_RPMB_FILE_NOT_FOUND：表示文件不存在。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Read(const char *filename, uint8_t *buf, size_t size, uint32_t *count);

/**
 * @brief 重命名RPMB中的文件。
 *
 * @param old_name 表示旧文件名。
 * @param new_name 表示新文件名。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确，或者文件名超过64字节。\n
 *         TEE_ERROR_RPMB_FILE_NOT_FOUND：表示文件不存在。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Rename(const char *old_name, const char *new_name);

/**
 * @brief 删除RPMB中的文件。
 *
 * @param filename 表示要删除的文件名。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确，或者文件名超过64字节。\n
 *         TEE_ERROR_RPMB_FILE_NOT_FOUND：表示文件不存在。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Rm(const char *filename);

/**
 * @brief 存储在RPMB分区中的文件状态，供{@link TEE_RPMB_FS_Stat}使用。
 *
 * @since 20
 */
struct rpmb_fs_stat {
    /** 表示文件的大小，以字节为单位。 */
    uint32_t size;
    /** 保留字段，当前未使用。 */
    uint32_t reserved;
};

/**
 * @brief 获取RPMB中的文件状态。
 *
 * @param filename 表示RPMB中的文件名。
 * @param stat 表示获取的文件状态信息。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确，或者文件名超过64字节。\n
 *         TEE_ERROR_RPMB_FILE_NOT_FOUND：表示文件不存在。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Stat(const char *filename, struct rpmb_fs_stat *stat);

/**
 * @brief 存储在RPMB分区中的磁盘状态，供{@link TEE_RPMB_FS_StatDisk}使用。
 *
 * @since 20
 */
struct rpmb_fs_statdisk {
    /** 表示RPMB分区的总大小。 */
    uint32_t disk_size;
    /** 表示TA已使用的大小。 */
    uint32_t ta_used_size;
    /** 表示RPMB分区的剩余空间大小。 */
    uint32_t free_size;
    /** 保留字段，当前未使用。 */
    uint32_t reserved;
};

/**
 * @brief 获取磁盘状态。
 *
 * @param stat 表示获取的磁盘状态信息。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：入参数不正确。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_StatDisk(struct rpmb_fs_statdisk *stat);

/**
 * @brief 文件属性定义，表示该文件在出厂重置过程中不能被擦除。
 *
 * @since 20
 */
#define TEE_RPMB_FMODE_NON_ERASURE (1U << 0)

/**
 * @brief 文件属性定义，表示清除文件的属性值。
 *
 * @since 20
 */
#define TEE_RPMB_FMODE_CLEAR 0

/**
 * @brief 设置RPMB中的文件属性。
 *
 * @param filename 表示RPMB中的文件名。
 * @param fmode 表示文件属性，当前支持{@link TEE_RPMB_FMODE_NON_ERASURE}和{@link TEE_RPMB_FMODE_CLEAR}两种属性，
 *              其他值将返回TEE_ERROR_BAD_PARAMETERS。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确，或者文件名超过64字节。\n
 *         TEE_ERROR_RPMB_FILE_NOT_FOUND：表示文件不存在。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_SetAttr(const char *filename, uint32_t fmode);

/**
 * @brief RPMB文件擦除，删除文件属性为可擦除文件，保留文件属性为不可擦除文件。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_RPMB_GENERIC：RPMB控制器一般错误。\n
 *         TEE_ERROR_RPMB_MAC_FAIL：RPMB控制器MAC校验错误。\n
 *         TEE_ERROR_RPMB_RESP_UNEXPECT_MAC：RPMB响应数据MAC校验错误。
 * @since 20
 */
TEE_Result TEE_RPMB_FS_Erase(void);

/**
 * @brief 枚举RPMB密钥状态的类型，供{@link TEE_RPMB_KEY_Status}使用。
 *
 * @since 20
 */
enum TEE_RPMB_KEY_STAT {
    /** RPMB密钥状态无效。 */
    TEE_RPMB_KEY_INVALID = 0x0,
    /** RPMB密钥已编程并且匹配正确。 */
    TEE_RPMB_KEY_SUCCESS,
    /** RPMB密钥未编程。 */
    TEE_RPMB_KEY_NOT_PROGRAM,
    /** RPMB密钥已编程，但未能匹配。 */
    TEE_RPMB_KEY_NOT_MATCH,
};

/**
 * @brief 获取RPMB密钥状态。
 *
 * @return TEE_RPMB_KEY_SUCCESS：RPMB密钥已编程并且匹配正确。\n
 *         TEE_RPMB_KEY_NOT_PROGRAM：RPMB密钥未编程。\n
 *         TEE_RPMB_KEY_NOT_MATCH：RPMB密钥已编程但未能匹配。\n
 *         TEE_RPMB_KEY_INVALID：RPMB密钥状态无效。
 * @since 20
 */
uint32_t TEE_RPMB_KEY_Status(void);

/**
 * @brief 枚举RPMB的类型，1表示ufs或emmc，2表示rpmc。
 *
 * @since 20
 */
typedef enum {
    /** ufs/emmc为安全类型。 */
    TEE_RPMB_SECLEVEL_HIGH = 0x1,
    /** rpmb 由 rpmc 模拟。 */
    TEE_RPMB_SECLEVEL_LOW = 0x2,
} TEE_RPMB_SECLEVEL;

/**
 * @brief 获取RPMB的安全级别，1表示ufs/emmc，2表示rpmc。
 *
 * @param sec_level 返回当前的安全级别。
 *
 * @return TEE_SUCCESS：成功，sec_level值有效。\n
 *         返回其他值表示失败，sec_level值无效。
 * @since 20
 */
TEE_Result tee_rpmb_fs_getseclevel(uint32_t *sec_level);

#ifdef __cplusplus
}
#endif

#endif
/** @} */